<?php

namespace App\Models\Traits;

use Carbon\Carbon;
use Illuminate\Support\Facades\Hash;
use Brick\Math\RoundingMode;
use Illuminate\Database\Eloquent\Builder;


trait HasUserIdentity
{
	public function isNormal()
	{
		return $this->grade === 'normal';
	}
	public function isNotNormal()
	{
		return $this->grade !== 'normal';
	}

	public function isVip()
	{
		return $this->grade === 'vip';
	}

	public function isNotVip()
	{
		return $this->grade !== 'vip';
	}

	

	public function isVipExpired()
	{
		if ($this->isNotVip()) {
			return true;
		}
		if (! $this->vip_expired_at) {
			return true;
		}
		$expiredAt = Carbon::parse($this->vip_expired_at);
		return Carbon::today()->gt($expiredAt);
	}
	
	public function isVipNotExpired()
	{
		return !$this->isVipExpired();
	}

	public function isValidVip()
	{
		return $this->isVip()
			and $this->isVipNotExpired()
			and !$this->is_locked;
	}


	public function isNotValidVip(): bool
	{
		return !$this->isValidVip();
	}

	public function isValidGoldIntern(): bool
	{
		return $this->hasValidGoldRecord() and !$this->is_locked;
	}

	public function isNotValidGoldIntern(): bool
	{
		return !$this->isValidGoldIntern();
	}

	public function isValidGoldMaster(): bool
	{
        $needChildren = cs('storm')->each_upgrade_needs_children;
		return $this->myGoldRecordsChildrenCount() >= (int)$needChildren
            and !$this->is_locked;
	}

	public function isNotValidGoldMaster(): bool
	{
		return !$this->isValidGoldMaster();
	}

	public function isPhoneBound()
	{
		return (bool)$this->phone;
	}

	public function isWeixinBound()
	{
		return (bool)$this->wx_openid;
	}

	public function isWeiminiBound()
	{
		return (bool)$this->wm_openid;
	}

	public function isAlipayBound()
	{
		return (bool)$this->alipay_user_id;
	}

	public function isBankBound()
	{
		return (bool)$this->cert_number;
	}

	public function isPayCodeSet()
	{
		return (bool)$this->pay_code;
	}

	public function isFreelanceAuth()
	{
		return  isset($this->freelance->id_no) ? (bool)$this->freelance->id_no : 0 ;
	}

	public function isAuthRealName()
	{
		return  isset($this->identify_num) ? (bool)$this->identify_num : 0 ;
	}

	public function isPayCodeValid($code)
	{
		if (empty($code)) return false;

		if (! Hash::check($code, $this->pay_code)) {
			return false;
		}

		return true;
	}

	public function ownOneSeconds()
	{
		$ownOneSeconds = 0;
		if($this->grade == 'vip'){

			if($this->user_level > 0){

				$vipProduce = cs("sale")->vip_produce_apple;

				$ownOneSeconds = big_decimal($vipProduce)->multipliedBy($this->user_level);


				//return $ownOneSeconds;
			}else{
				$normalVipProduce = cs("sale")->normal_vip_produce_apple;
				
				$ownOneSeconds = big_decimal($normalVipProduce);
				//return $ownOneSeconds;

			}

			
			
		}
//
		
		if($ownOneSeconds){
			return $ownOneSeconds->dividedBy(86400 ,8 , RoundingMode::HALF_UP);
		}
		

		return big_decimal(0);

	}


	public function ownOneDays()
	{

		if($this->is_stop){

			return 0;
		}
		if($this->grade == 'vip'){

			if($this->user_level > 0){

				$vipProduce = cs("sale")->vip_produce_apple;

				$ownOneSeconds = big_decimal($vipProduce)->multipliedBy($this->user_level)->toScale(2, RoundingMode::HALF_UP);

				return $ownOneSeconds;
			}else{
				$normalVipProduce = cs("sale")->normal_vip_produce_apple;
				
				$ownOneSeconds = big_decimal($normalVipProduce)->toScale(2, RoundingMode::HALF_UP);
				return $ownOneSeconds;

			}
			
		}
		

		return 0;

	}




	public function allowedPart($i)
	{
		if($i < 2){

			return true;
		}else{

			if(big_decimal($this->team_level)->isGreaterThan(4)){

				return true;
			}else{

				if(big_decimal($this->team_level)->plus(2)->isGreaterThanOrEqualTo($i)){

					return true;
				}

			}
			


		}

		return false;

	}

	public function allProduceApplesOneSeconds()
	{

		if($this->is_stop){

			return big_decimal(0);
		}
		$allProductApple = $this->ownOneSeconds();

		

		if($this->oneLevelTeamSeconds()->isGreaterThan(0)){

			$allProductApple = $allProductApple->plus((string)$this->oneLevelTeamSeconds());
			
			
		}


		if($this->moreLevelTeamSeconds(2)->isGreaterThan(0)){

			$allProductApple = $allProductApple->plus((string)$this->moreLevelTeamSeconds(2));
		}


		$trees = $this->appleTreeRecords()->join('apple_trees','apple_trees.id','apple_trees_records.apple_tree_id')->where("expired_at",">",Carbon::now())->sum('apple_trees.produce_apples');
		
		if($trees){
			$oneDayTree = big_decimal($trees)->dividedBy(86400*30 ,8 , RoundingMode::HALF_UP);;
			if($allProductApple){
				$allProductApple = $allProductApple->plus($oneDayTree);

			}else{
				$allProductApple = big_decimal($oneDayTree);

			}

		}

		return $allProductApple;
	}

	public function childOwnProduceApplesOneSeconds()
	{

		$oneSecond = $this->ownOneSeconds();
		$oneLevelPercent = cs('sale')->vip_one_level_brokage_percent / 100;
		if($oneSecond){
			
			return  $oneSecond->multipliedBy($oneLevelPercent);
		
		}

		return $oneSecond;
	}

	public function dividendChildApples()
	{
		$thisSecondApples = $this->childOwnProduceApplesOneSeconds();

		if($thisSecondApples){

			$thisHourApples = $thisSecondApples->multipliedBy(3600);
			$all = $thisHourApples->plus($this->dividend_parent_reward);
			$this->update(['dividend_parent_reward'=>$all]);
		}

	}


	public function dividendApplesRate()
	{
		$oneDay = $this->ownOneDays();
		$oneLevelPercent = cs('sale')->vip_one_level_brokage_percent / 100;

		if($oneDay){
			
			return  $oneDay->multipliedBy($oneLevelPercent)->toScale(2, RoundingMode::HALF_UP);
		
		}

		return $oneDay;

	}

	public function ownProduceApples()
    {
        return $this->userApples()->where('remark','own_tree_produce_apples')->sum('money');
    }

    public function dividentApples()
    {
        return $this->userApples()->where(function (Builder $query) {
 						 $query->where('remark','own_tree_produce_apples')->orWhere('remark', 'garden_produce_apples')->orWhere('remark', '1_tree_produce_apples')->orWhere('remark', '2_tree_produce_apples');
				})->sum('money');
    }

      public function childrenDividendApples()
    {
        return $this->userApples()->where('remark', '1_tree_produce_apples')->sum('money');
    }

     public function secondDividendApples()
    {
        return $this->userApples()->where('remark', '2_tree_produce_apples')->sum('money');
    }

    

    public function childrenDividendRewards()
    {
        return $this->rewards()->where('remark', 'first_level')->sum('money');
    }

     public function secondDividendRewards()
    {
        return $this->rewards()->where('remark', 'second_level')->sum('money');
    }

     public function dividentRewards()
    {
        return $this->rewards()->where(function (Builder $query) {
 						 $query->where('remark','own_order')->orWhere('remark', 'first_level')->orWhere('remark', 'second_level')->orWhere('remark', 'rewards_refund');
				})->sum('money');
    }


     public function theSameMonthRewards()
    {
		    	// 获取当前时间点
		$now = Carbon::now();
		 
		// 计算上个月的起始日期和结束日期
		$startOfLastMonth = $now->subMonths(2)->day(20);
		$endOfLastMonth = $now->subMonths(1)->day(19);
        return $this->rewards()->where(function (Builder $query) {
 						 $query->where('remark','own_order')->orWhere('remark', 'first_level')->orWhere('remark', 'second_level')->orWhere('remark', 'rewards_refund');
				}) ->whereBetween('created_at', [$startOfLastMonth, $endOfLastMonth])->where('is_settle',false)->sum('money');
    }

    public function theLastMonthRewards()
    {
        return $this->rewards()->where(function (Builder $query) {
 						 $query->where('remark','own_order')->orWhere('remark', 'first_level')->orWhere('remark', 'second_level')->orWhere('remark', 'rewards_refund');
				})->where('is_settle',false)->sum('money');
    }

      public function dividendSettleRewards()
    {
        return $this->rewards()->where(function (Builder $query) {
 						 $query->where('remark','own_order')->orWhere('remark', 'first_level')->orWhere('remark', 'second_level');
				})->where('is_settle',true)->sum('money');
    }


    

    public function dividendParentApples()
    {
    	if(empty($this->parent_id)){

    		return 0;
    	}
        return $this->childrenApples()->where('user_id',$this->parent_id)->sum('money');
    }


     public function oneDayParentApples()
    {
    	if(empty($this->parent_id)){

    		return 0;
    	}

       $moreTeamSeconds = big_decimal(0)->plus($this->ownOneDays());
       $moreLevelPercent = cs('sale')->vip_one_level_brokage_percent / 100;
       if($moreTeamSeconds){

			return  $moreTeamSeconds->multipliedBy($moreLevelPercent);
		
		}

		return $moreTeamSeconds;
    }

    public function dividendParentRewards()
    {
    	if(empty($this->parent_id)){

    		return 0;
    	}

        return $this->childrenRewards()->where('user_id',$this->parent_id)->sum('money');
    }


    public function myNowApples()
    {
        
        $lastProduce = $this->userApples()->where('remark','own_tree_produce_apples')->orderByDesc('id')->first();
        if(empty($lastProduce)){
        	if($this->isValidVip()){
        		$lastProduceTime = $this->vipPurchases()->whereNotNull('paid_at')->orderBy('id')->first();
        		if($lastProduceTime){
        			$lastProduceTime = $lastProduceTime->created_at->toDatetimeString();
        		}else{

        			return $this->apples;
        		}

        	}else{
        		return $this->apples;

        	}
        	
        }else{

        	$lastProduceTime  = $lastProduce->created_at->toDatetimeString();
        }
        
        $myNowApples = big_decimal($this->apples);
        if(strtotime($lastProduceTime) < time()){

        	$seconds = time() - strtotime($lastProduceTime) ;
        	$myNowApples = $myNowApples->plus($this->allProduceApplesOneSeconds()->multipliedBy($seconds));

        }

        $myNowApples =  (string)$myNowApples;

        return $myNowApples;
    }


    public function needUserOrderCount()
    {

    	$count = $this->myVipChildren()->count();
    	$needCount =  $count * cs("sale")->children_order_percent /100;
    	
    	return ceil($needCount);
    }

    public function isDetect()
	{
		
		return $this->detect()->exists() ? 1 : 0;
	}
    
}
